package cn.mw.cmdb.processor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.InstanceInfoExtend;
import cn.mw.cmdb.entity.OrgTreeView;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.util.AssetsTool;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.view.ViewConvertContext;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.api.user.MwUserApi;
import cn.mw.microMonitorCommon.entity.userDTO.OrgDTO;
import cn.mw.microMonitorCommon.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

import static cn.mw.cmdb.util.ValConvertUtil.intValueConvert;
import static cn.mw.cmdb.util.ValConvertUtil.longValueConvert;
@Slf4j
public class TreeProcessorOrg implements TreeProccessorTable {
    private CmdbServiceManage cmdbServiceManage;

    public TreeProcessorOrg(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    public String systemInterfaceConfigKey = "system.interfaceInfo.configName";

    public String SCMONITORSYSTEMKEY = "scMonitorSystem";

    @Override
    public List genTreeData(TableDataProcessorContext context) throws Exception {
        List<TreeView> ret = new ArrayList<>();
        MwUserApi mwUserApi = (MwUserApi) context.get(ViewConvertContext.MwuserApiKey);
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);

        List<String> fields = new ArrayList<>();
        fields.add(CMDBTool.getFieldName(InstanceInfo::getId));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getPath));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getInstanceName));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getOrgs));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getOrgIds));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getItemAssetsStatus));
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setFields(fields);
        SubCondition subCondition = new SubCondition(CriteriaOpsType.ne.name(), null);
        instanceSearchParam.addSubCondition(CMDBTool.getFieldName(InstanceInfo::getOrgs), subCondition);

        BeanUtil.copyProperties(context.getTableSearchParam(), instanceSearchParam, CopyOptions.create().setIgnoreNullValue(true));

        List<InstanceInfoExtend> list = instanceService.aggregateList(instanceSearchParam);
        Set<Long> orgIdSet = new HashSet<>();
        Map<Long, List<InstanceInfoExtend>> id2InstancesMap = new HashMap<>();
        String systemInterfaceConfig = SpringUtils.getPropertiesValue(systemInterfaceConfigKey);
        if (SCMONITORSYSTEMKEY.equals(systemInterfaceConfig)) {
            if (null != list) {

                Map<Long, Long> collect = list.stream().filter(t -> t.getOrgs() != null && !t.getOrgs().isEmpty()).flatMap(t -> t.getOrgs().stream().filter(orgList -> orgList != null && !orgList.isEmpty()).flatMap(Collection::stream)).collect(Collectors.groupingBy(s -> s, Collectors.counting()));
                log.info("orgsMapCount::"+collect);
                Map<Long,Long> map = new HashMap<>();
                for (InstanceInfoExtend instanceInfo : list) {
                    Set<Long> dsiOrgIdSet = new HashSet<>();

                    if (null != instanceInfo.getOrgs()) {
                        for (List<Long> orgPath : instanceInfo.getOrgs()) {
                            if (null != orgPath) {
                                orgPath.forEach(item -> {
                                    if(!dsiOrgIdSet.contains(item)){
                                        orgIdSet.add(item);
                                        dsiOrgIdSet.add(item);
                                        if (!id2InstancesMap.containsKey(item)) {
                                            id2InstancesMap.put(item, new ArrayList<>());
                                        }
                                        id2InstancesMap.get(item).add(instanceInfo);
                                    }
                                });
                            }
                        }
                    }
                }
            }
        } else {
            if (null != list) {
                for (InstanceInfoExtend instanceInfo : list) {
                    if (null != instanceInfo.getOrgs() && null != instanceInfo.getOrgIds()) {
                        for (Long orgPath : instanceInfo.getOrgIds()) {
                            if (null != orgPath) {
                                for (List<Long> orgs : instanceInfo.getOrgs()) {
                                    for (Long org : orgs) {
                                        orgIdSet.add(org);
                                    }
                                }
                                if (!id2InstancesMap.containsKey(orgPath)) {
                                    id2InstancesMap.put(orgPath, new ArrayList<>());
                                }
                                id2InstancesMap.get(orgPath).add(instanceInfo);
//                            orgPath.forEach(item -> {
//                                if (!id2InstancesMap.containsKey(item)) {
//                                    id2InstancesMap.put(item, new ArrayList<>());
//                                }
//                                id2InstancesMap.get(item).add(instanceInfo);
//                            });
                            }
                        }
                    }
                }
            }
        }
        if (orgIdSet.size() > 0) {
            List<OrgDTO> orgDTOS = mwUserApi.getOrgListByOrgIds(orgIdSet.stream().toList());
            if (null != orgDTOS) {
                for (OrgDTO orgDTO : orgDTOS) {
                    OrgTreeView orgTreeView = new OrgTreeView(orgDTO.getId().toString()
                            , orgDTO.getPid().toString(), orgDTO.getOrgName());
                    ret.add(orgTreeView);
                }
            }
        }

        for (TreeView treeView : ret) {
            long id = longValueConvert(treeView.getId());
            if (id2InstancesMap.containsKey(id)) {
                treeView.setCount(intValueConvert(id2InstancesMap.get(id).size()));
                treeView.setItemAssetsStatus(AssetsTool.calcItemAssetsStatus(id2InstancesMap.get(id), treeView));
            }
        }

        return ret;
    }
}
